---
type: tutorial
title: Создание страницы индекса тегов
description: |-
  Руководство: Создайте свой первый блог в Astro —
  Используйте все, что вы узнали до сих пор, чтобы создать страницу индекса тегов
i18nReady: true
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';



Теперь, когда у вас есть отдельные страницы для каждого тега, давайте создадим ссылки на них.

<PreCheck>
  - Добавить новую страницу, используя шаблон маршрутизации `/my-folder/index.astro`
  - Отобразить список всех ваших уникальных тегов, сделав ссылку на каждую страницу тега
  - Обновить ваш сайт, добавив навигационные ссылки на эту новую страницу Теги
</PreCheck>

## Используйте шаблон маршрутизации `/folder/index.astro`

Чтобы добавить страницу индекса тегов на ваш веб-сайт, вы можете создать новый файл `src/pages/tags.astro`.

Однако, поскольку у вас уже есть каталог `/tags/`, вы можете воспользоваться другим шаблоном маршрутизации в Astro и хранить все свои файлы, связанные с тегами, вместе.

<Box icon="puzzle-piece">

## Попробуйте сами - Создайте страницу индекса тегов

1. Создайте новый файл `index.astro` в каталоге `src/pages/tags/`.

2. Перейдите по адресу `http://localhost:4321/tags` и убедитесь, что ваш сайт теперь содержит страницу по этому URL. Она будет пустой, но она будет существовать.

3. Создайте минимальную страницу в `src/pages/tags/index.astro`, которая использует ваш макет. Вы уже делали это раньше!

    <details>
      <summary>Раскройте, чтобы увидеть шаги</summary>

      1. Создайте новый компонент страницы в `src/pages/tags/`.

          <details>
          <summary>Показать имя файла</summary>
          ```
          index.astro
          ```
          </details>

      2. Импортируйте и используйте `<BaseLayout>`.

          <details>
          <summary>Показать код</summary>
          ```astro title=" src/pages/tags/index.astro"
          ---
          import BaseLayout from '../../layouts/BaseLayout.astro';
          ---
          <BaseLayout></BaseLayout>
          ```
          </details>

      3. Определите заголовок страницы и передайте его в ваш макет в качестве атрибута компонента.

          <details>
          <summary>Показать код</summary>
          ```astro title="src/pages/tags/index.astro" ins={3} "pageTitle"
          ---
          import BaseLayout from '../../layouts/BaseLayout.astro';
          const pageTitle = "Индекс тегов";
          ---
          <BaseLayout pageTitle={pageTitle}></BaseLayout>
          ```
          </details>
    </details>

4. Проверьте предварительный просмотр в браузере еще раз, и у вас должна быть отформатированная страница, готовая к добавлению контента!

</Box>

## Создайте массив тегов

Ранее вы отображали элементы в списке из массива с помощью `map()`. Как бы вы определили массив всех ваших тегов и затем отобразили их в списке на этой странице?

<details>
    <summary>Посмотрите код</summary>

    ```astro title="src/pages/tags/index.astro"
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const tags = ["astro", "successes", "community", "setbacks", "learning in public"];
    const pageTitle = "Индекс тегов";
    ---
    <BaseLayout pageTitle={pageTitle}>
      <ul>
        {tags.map((tag) => <li>{tag}</li>)}
      </ul>
    </BaseLayout>
    ```
</details>

Вы можете сделать это, но вам придется возвращаться к этому файлу и обновлять свой массив каждый раз, когда вы используете новый тег в будущей записи в блоге.

К счастью, у вас уже есть способ получить данные из всех ваших файлов Markdown в одной строке кода, а затем вернуть список всех ваших тегов.


1. В файле `src/pages/tags/index.astro` добавьте строку кода в скрипт frontmatter, которая даст вашей странице доступ к данным из каждого файла блога `.md`.

    <details>
    <summary>Посмотрите код</summary>
    ```astro title = "src/pages/tags/index.astro" ins={3}
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const pageTitle = "Индекс тегов";
    ---
    ```
    </details>

2. Затем добавьте следующую строку JavaScript в ваш компонент страницы. Это то же самое, что мы использовали в `src/pages/tags/[tag].astro`, чтобы вернуть список уникальных тегов.

    ```astro title = "src/pages/tags/index.astro" ins={4}
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
    const pageTitle = "Индекс тегов";
    ---

    ```

## Создайте свой список тегов

Вместо создания элементов в неупорядоченном списке на этот раз создайте один `<p>` для каждого элемента внутри `<div>`. Шаблон должен вам быть знакомым!

1. Добавьте следующий код в ваш шаблон компонента:

    ```astro title="src/pages/tags/index.astro" ins={2}
      <BaseLayout pageTitle={pageTitle}>
        <div>{tags.map((tag) => <p>{tag}</p>)}</div>
      </BaseLayout>
    ```
   В предварительном просмотре в браузере убедитесь, что вы видите свои теги в списке.

2. Чтобы сделать каждый тег ссылкой на свою собственную страницу, добавьте следующую ссылку `<a>` для каждого имени тега:

    ```astro title="src/pages/tags/index.astro" '/tags/${tag}'
    <BaseLayout pageTitle={pageTitle}>
      <div>
        {tags.map((tag) => (
          <p><a href={`/tags/${tag}`}>{tag}</a></p>
        ))}
      </div>
    </BaseLayout>
    ```

## Добавьте стили к вашему списку тегов

1. Добавьте следующие CSS-классы, чтобы стилизовать как ваш `<div>`, так и каждый `<p>`, который будет сгенерирован. Примечание: Astro использует синтаксис HTML для добавления имен классов!

    ```astro title="src/pages/tags/index.astro" 'class="tags"' 'class="tag"'
    <BaseLayout pageTitle={pageTitle}>
    <div class="tags">
      {tags.map((tag) => (
        <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
      ))}
    </div>
    </BaseLayout>
    ```

2. Определите эти новые CSS-классы, добавив следующий тег `<style>` на этой странице:

    ```astro title="src/pages/tags/index.astro"
    <style>
      a {
        color: #00539F;
      }

      .tags {
        display: flex;
        flex-wrap: wrap;
        margin: 0 auto;
      }

      .tag {
        margin: 0.25em;
        border: dotted 1px #a1a1a1;
        border-radius: .5em;
        padding: .5em 1em;
        font-size: 1.15em;
        background-color: #F8FCFD;
      }
    </style>
    ```

3. Проверьте предварительный просмотр в браузере по адресу `http://localhost:4321/tags`, чтобы убедиться, что у вас есть новые стили и что каждый из тегов на странице имеет рабочую ссылку на свою собственную страницу тега.

### Проверка кода

Вот как должна выглядеть ваша новая страница:

```astro title="src/pages/tags/index.astro"
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = await Astro.glob('../posts/*.md');
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
const pageTitle = "Tag Index";
---
<BaseLayout pageTitle={pageTitle}>
  <div class="tags">
    {tags.map((tag) => (
      <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
  </div>
</BaseLayout>
<style>
  a {
    color: #00539F;
  }

  .tags {
    display: flex;
    flex-wrap: wrap;
    margin: 0 auto;
  }

  .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
  }
</style>
```

## Добавьте эту страницу в вашу навигацию

В данный момент вы можете перейти по адресу `http://localhost:4321/tags` и увидеть эту страницу. С этой страницы вы можете переходить по ссылкам на отдельные страницы тегов.

Но вам все еще нужно сделать эти страницы доступными с других страниц вашего веб-сайта.

1. В вашем компоненте `Navigation.astro` добавьте ссылку на эту новую страницу индекса тегов.

    <details>
    <summary>Покажи мне код</summary>
    ```astro title="src/components/Navigation.astro" ins={4}
    <a href="/">Главная</a>
    <a href="/about/">О нас</a>
    <a href="/blog/">Блог</a>
    <a href="/tags/">Теги</a>
    ```
    </details>

<Box icon="puzzle-piece">

## Задание: Включите теги в макет вашей записи блога

Теперь у вас есть весь необходимый код, чтобы также отображать список тегов на каждой странице блога и связывать их со страницами тегов. У вас уже есть готовая работа, которую вы можете использовать повторно!

Следуйте инструкциям ниже, а затем проверьте свою работу, сравнив ее с [финальным образцом кода](#проверка-кода-разметкапостаmarkdown).

1. Скопируйте `<div class="tags">`... `</div>` и `<style>...</style>` из `src/pages/tags/index.astro` и используйте их внутри `MarkdownPostLayout.astro`:

  ```astro title="src/layouts/MarkdownPostLayout.astro" ins={13-17, 21-40}
  ---
  import BaseLayout from './BaseLayout.astro';
  const { frontmatter } = Astro.props;
  ---
  <BaseLayout pageTitle={frontmatter.title}>
    <p><em>{frontmatter.description}</em></p>
    <p>{frontmatter.pubDate.slice(0,10)}</p>

    <p>Написал: {frontmatter.author}</p>

    <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />

    <div class="tags">
      {tags.map((tag) => (
        <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
      ))}
    </div>

    <slot />
  </BaseLayout>
  <style>
    a {
      color: #00539F;
    }

    .tags {
      display: flex;
      flex-wrap: wrap;
      margin: 0 auto;
    }

    .tag {
      margin: 0.25em;
      border: dotted 1px #a1a1a1;
      border-radius: .5em;
      padding: .5em 1em;
      font-size: 1.15em;
      background-color: #F8FCFD;
    }
  </style>
```

Перед тем, как этот код заработает, вам нужно внести **одну небольшую правку** в код, который вы вставили в `MarkdownPostLayout.astro`. Можете понять, что это за правка?

<details>
<summary>Дайте мне подсказку</summary>

Как другие свойства (например, заголовок, автор и т. д.) записаны в вашем макете шаблона? Как ваш макет получает свойства от отдельной записи блога?
</details>

<details>
<summary>Дайте мне еще одну подсказку!</summary>

Чтобы использовать свойства (переданные значения) из файла `.md` в вашем макете, например, теги, вам нужно добавить префикс к значению.

<details>
<summary>Покажите мне код!</summary>

```astro title="src/layouts/MarkdownPostLayout.astro" "frontmatter"
    <div class="tags">
      {frontmatter.tags.map((tag) => (
        <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
      ))}
    </div>
```
</details>
</details>

</Box>

### Проверка кода: РазметкаПостаMarkdown

Чтобы проверить свою работу, или если вы просто хотите скопировать полный, корректный код в `MarkdownPostLayout.astro`, вот как должен выглядеть ваш компонент Astro:

```astro title="src/layouts/MarkdownPostLayout.astro"
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
  <p><em>{frontmatter.description}</em></p>
  <p>{frontmatter.pubDate.slice(0,10)}</p>

  <p>Автор: {frontmatter.author}</p>

  <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />

  <div class="tags">
    {frontmatter.tags.map((tag) => (
      <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
  </div>

  <slot />
</BaseLayout>
<style>
  a {
    color: #00539F;
  }

  .tags {
    display: flex;
    flex-wrap: wrap;
    margin: 0 auto;
  }

  .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
  }
</style>
```



<Box icon="question-mark">

### Проверьте свои знания

Сопоставьте каждый файловый путь со вторым файловым путем, который создаст страницу по тому же маршруту.

1. `src/pages/categories.astro`

    <MultipleChoice>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option>`src/pages/posts/index.astro`</Option>
      <Option>`src/components/shoes/Shoe.astro`</Option>
      <Option isCorrect>`src/pages/categories/index.astro`</Option>
    </MultipleChoice>

2. `src/pages/posts.astro`

    <MultipleChoice>
      <Option>`src/pages/products/shoes.astro`</Option>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option isCorrect>`src/pages/posts/index.astro`</Option>
      <Option>`src/pages/categories/index.astro`</Option>
    </MultipleChoice>

3. `src/pages/products/shoes/index.astro`

    <MultipleChoice>
      <Option isCorrect>`src/pages/products/shoes.astro`</Option>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option>`src/pages/posts/index.astro`</Option>
      <Option>`src/components/shoes/Shoe.astro`</Option>
    </MultipleChoice>

</Box>

<Box icon="check-list">

## Чек-лист

<Checklist>
- [ ] Я умею использовать функцию маршрутизации Astro `/pages/folder/index.astro`.
</Checklist>
</Box>

### Ресурсы

- [Статическая маршрутизация в Astro](/ru/guides/routing/#статические-маршруты)
